<?php
/**
 * Created by PhpStorm.
 * User: wodrow
 * Date: 18-7-9
 * Time: 下午3:23
 */

namespace common\models\db;


use common\components\tools\ArrayHelper;
use common\components\tools\Html;
use common\components\tools\Security;
use common\components\tools\Url;
use common\config\Env;
use common\members\wodrow\tools\Color;
use common\members\wodrow\tools\Model;
use home\members\wodrow\profile_box\ProfileBox;
use yii\base\Exception;
use yii\web\HttpException;
use yii\web\IdentityInterface;

/**
 * Class User
 * @package common\models\db
 *
 * @property Action[] $createdActions
 * @property Yii2App[] $createdApps
 * @property Menu[] $createdMenus
 * @property Role[] $cretedRoles
 * @property RoleUser[] $roleUser
 * @property Role[] $roles
 * @property string $textAvatarUrl
 * @property string $profileUrl
 * @property string $profileName
 * @property string $profileBoxUrl
 */
class User extends \common\models\db\tables\User implements IdentityInterface
{
    public function rules()
    {
        $PR = parent::rules();
        $r = ArrayHelper::merge($PR, [
            [['idcard', 'mobile', 'username', 'email', 'nickname', 'avatar_url'], 'default'],
            ['mobile', 'ruleCheckMobile'],
            ['username', 'ruleCheckUsername'],
        ]);
        return $r;
    }

    public function ruleCheckMobile($attribute, $params)
    {
        if ($this->isNewRecord){
            if (self::findOne(['mobile_pre' => $this->mobile_pre, 'mobile' => $this->mobile])){
                $this->addError($attribute, "手机号已存在");
            }
        }
    }

    public function ruleCheckUsername($attribute, $params)
    {
        if (is_numeric($this->username)){
            $this->addError($attribute, "用户名不能为纯数字");
        }
        if (mb_strlen($this->username, 'utf-8') < 4){
            $this->addError($attribute, "用户名必须6位以上");
        }
    }

    const STATUS_DELETE = -100;
    const STATUS_EMAIL_UNACTIVE = 9;
    const STATUS_ACTIVE = 10;
    public static function getStatus()
    {
        return [
            self::STATUS_ACTIVE => '正常',
            self::STATUS_DELETE => '账户已删除',
            self::STATUS_EMAIL_UNACTIVE => '账户email未激活',
        ];
    }

    const IS_SUPER_TRUE = 1;
    const IS_SUPER_FALSE = 0;
    public static function getIsSuper()
    {
        return [
            self::IS_SUPER_FALSE => '否',
            self::IS_SUPER_TRUE => '是',
        ];
    }

    const SIGNUP_CODE_PRE = 'signup_code__';
    const RESET_PASSWORD_CODE_PRE = 'reset_password_code__';
    const PASSWORD_STORE_PRE = 'password_store_code__';
    const STORE_DATA_PRE = 'store_data__';

    /**
     * @param $password
     * @throws \yii\base\Exception
     */
    public function setPassword($password)
    {
        $this->password_hash = \Yii::$app->security->generatePasswordHash($password);
        $this->tp_pwd = Security::think_encrypt($password);
    }

    public function validatePassword($password)
    {
        return \Yii::$app->security->validatePassword($password, $this->password_hash);
    }

    /**
     * @param string $path 相对路径
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    public function saveAvatar($path)
    {
        $s = new Smms();
        $s->uploadLocalFile(\Yii::getAlias('@wroot').$path);
        $this->avatar_url = $s->url;
        if ($this->save()) {
            \Yii::$app->session->addFlash('success', "头像修改成功");
        } else {
            \Yii::$app->session->addFlash('error', "头像修改失败:" . Model::getModelError($this));
        }
    }

    /**
     * @param int $w
     * @param int $h
     * @param array $options
     * @return string <img src="..." />
     * @throws \Exception
     */
    public function getAvatarImg($w = 200, $h = 200, $options = [])
    {
        $options = ArrayHelper::merge([
//            'class' => "img-circle",
            'alt' => $this->username,
        ], $options);
        $options['width'] = $w;
        $options['height'] = $h;
        if ($this->avatar_url){
            $str = Html::img($this->avatar_url, $options);
        }else{
            $str = Html::img($this->textAvatarUrl, $options);
        }
        return $str;
    }

    /**
     * @return string $textAvatarUrl
     */
    public function getTextAvatarUrl()
    {
        $key = "text_avatar_url-".$this->id;
        if(YII_ENV == 'dev')\Yii::$app->cache->delete($key);
        $url = \Yii::$app->cache->get($key);
        if (!$url){
            $hex = bin2hex($this->random_string);
            $bg_color = substr($hex, 0, 6);
            $f_color = Color::rgb2contrast($bg_color);
            $text = $this->profileName;
            $text = mb_substr($text, 0, 2);
            $url = Env::getUrls()['webapi_url']."/public/text-avatar-image?text={$text}&backgroundColor={$bg_color}&fontColor={$f_color}";
            \Yii::$app->cache->set($key, $url, 3600);
        }
        return $url;
    }

    /**
     * 获取用户个人主页url
     * @return string $profileUrl
     */
    public function getProfileUrl()
    {
        switch (\Yii::$app->appinfo->name){
            case Env::$yii2appid_home:
                return Url::to(['/user/profile/index', 'id' => $this->id], true);
//                return Url::toRoute(['/user/profile/index', 'id' => $this->id]);
//                return \Yii::$app->urlManager->createUrl(['/user/profile/index', 'id' => $this->id]);
                break;
            default:
                return \common\config\Env::getUrls()['home_url']."/user/profile/index/".\Yii::$app->user->id.\common\config\Env::$home_suffix;
                break;
        }
    }

    /**
     * 获取用户显示用户名
     * @return string $profileName
     */
    public function getProfileName()
    {
        if ($this->nickname)return$this->nickname;
        if ($this->username)return$this->username;
        if ($this->mobile)return$this->mobile;
        if ($this->email)return$this->email;
    }

    /**
     * 获取用户个人box主页url
     * @return string $profileUrl
     */
    public function getProfileBoxUrl()
    {
        switch (\Yii::$app->appinfo->name){
            case Env::$yii2appid_home:
                return Url::to(['/user/profile/box', 'id' => $this->id], true);
//                return Url::toRoute(['/user/profile/index', 'id' => $this->id]);
//                return \Yii::$app->urlManager->createUrl(['/user/profile/index', 'id' => $this->id]);
                break;
            default:
                return \common\config\Env::getUrls()['home_url']."/user/profile/box/".\Yii::$app->user->id.\common\config\Env::$home_suffix;
                break;
        }
    }

    /**
     * 可以显示小个人中心
     * @param $body
     * @param $options
     * @return string <a href='...'>...</a>
     * @throws Exception
     * @throws \Exception
     */
    public function getProfileBoxA($body, $options = [])
    {
        if (\Yii::$app->appinfo->name != Env::$yii2appid_home){
            throw new Exception("必须在".Env::$yii2appid_home."应用");
        }
        $a = ProfileBox::widget([
            'body' => $body,
            'options' => $options,
            'user' => $this,
        ]);
        return $a;
    }

    public static function findIdentity($id)
    {
        return static::findOne(['id' => $id, 'status' => self::STATUS_ACTIVE]);
    }

    public static function findIdentityByAccessToken($token, $type = null)
    {
    }

    public function getId()
    {
        return $this->getPrimaryKey();
    }

    public function getAuthKey()
    {
        return $this->auth_key;
    }

    public function validateAuthKey($authKey)
    {
        return $this->getAuthKey() === $authKey;
    }

    /**
     * @param string $pre
     * @param int $duration
     * @return mixed
     * @throws \yii\base\Exception
     */
    public function generateCode($pre = self::SIGNUP_CODE_PRE, $duration = 3600)
    {
        $key = $pre . $this->email;
        $code = \Yii::$app->cache->get($key);
        if ($code) {
            \Yii::$app->cache->delete($key);
        }
        \Yii::$app->cache->set($key, \Yii::$app->security->generateRandomString(), $duration);
        $code = \Yii::$app->cache->get($key);
        return $code;
    }

    public function validateCode($code, $pre = self::SIGNUP_CODE_PRE)
    {
        $bool = 0;
        $key = $pre . $this->email;
        if ($code == \Yii::$app->cache->get($key)) {
            $bool = 1;
            \Yii::$app->cache->delete($key);
        }
        return $bool;
    }

    public function setCacheData($data, $pre = self::STORE_DATA_PRE, $duration = 3600)
    {
        $key = $pre . $this->username;
        $x = \Yii::$app->cache->get($key);
        if ($x) {
            \Yii::$app->cache->delete($key);
        }
        return \Yii::$app->cache->set($key, $data, $duration);
    }

    public function getCacheData($pre = self::STORE_DATA_PRE)
    {
        $key = $pre . $this->username;
        return \Yii::$app->cache->get($key);
    }

    public function deleteCacheData($pre = self::STORE_DATA_PRE)
    {
        $key = $pre . $this->username;
        return \Yii::$app->cache->delete($key);
    }


    /**
     * @throws \yii\base\Exception
     */
    public function generateToken()
    {
        $token = \Yii::$app->security->generateRandomString(50);
        if (self::findOne(['token' => $token])) {
            $this->generateToken();
        } else {
            $this->token = $token;
            $this->key = \Yii::$app->security->generateRandomString(32);
        }
    }

    /**
     * @param bool $insert
     * @return bool
     * @throws HttpException
     * @throws \Exception
     */
    public function beforeSave($insert)
    {
        if (!$this->random_string){
            $this->random_string = \Yii::$app->security->generateRandomString();
        }
        if (parent::beforeSave($insert)) {
            if (!$this->mobile && !$this->username && !$this->email && !$this->idcard) {
                throw new HttpException(88151124, '账号的手机号，用户名，邮箱，身份证号不能同时为空');
            }
            return true;
        } else {
            return false;
        }
    }

    /**
     * @return \yii\db\ActiveQuery
     */
    public function getCreatedActions()
    {
        return $this->hasMany(Action::className(), ['created_by' => 'id']);
    }

    /**
     * @return \yii\db\ActiveQuery
     */
    public function getCreatedApps()
    {
        return $this->hasMany(Yii2App::className(), ['created_by' => 'id']);
    }

    /**
     * @return \yii\db\ActiveQuery
     */
    public function getCreatedMenus()
    {
        return $this->hasMany(Menu::className(), ['created_by' => 'id']);
    }

    /**
     * @return \yii\db\ActiveQuery
     */
    public function getCreatedRoles()
    {
        return $this->hasMany(Role::className(), ['created_by' => 'id']);
    }

    /**
     * @return \yii\db\ActiveQuery
     */
    public function getRoleUsers()
    {
        return $this->hasMany(RoleUser::className(), ['user_id' => 'id']);
    }

    /**
     * @return \yii\db\ActiveQuery
     */
    public function getRoles()
    {
        return $this->hasMany(Role::className(), ['id' => 'role_id'])->viaTable('{{%role_user}}', ['user_id' => 'id']);
    }
}